package mental_connect.backend.backend_ym.filter;

import mental_connect.backend.backend_ym.entity.AccountInfo;
import mental_connect.backend.backend_ym.service.JwtTokenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class JwtTokenFilter extends OncePerRequestFilter {
    @Autowired
    @Qualifier("accountInfo")
    private RedisTemplate<String, AccountInfo> redisTemplate;
    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        if("/login".equals(httpServletRequest.getRequestURI()) || "/register".equals(httpServletRequest.getRequestURI())){
            filterChain.doFilter(httpServletRequest,httpServletResponse);
            return;
        }
        String token = httpServletRequest.getHeader("token");
        //从redis里面获取accountInfo信息转化为accountinfo对象
        String key = JwtTokenService.getRedisKey(token);
        //String[] split = key.split("_");
        //Set<String> keys = redisTemplate.keys("*" + split[1]);
        //List<Timestamp> collect = Objects.requireNonNull(keys).stream().map(item -> {
        //    String time = item.substring(0, 14);
        //    return DateUtil.stringToTimestamp(time);
        //}).collect(Collectors.toList());
        //Optional<Timestamp> max = collect.stream().max(Timestamp::compareTo);
        //Optional<List<Timestamp>> timestamps = max.map(m -> collect.stream().filter(i -> !m.equals(i)).collect(Collectors.toList()));
        //timestamps.ifPresent(i -> {
        //    i.forEach(t -> {
        //        String time = DateUtil.timestampToString(t, "yyyyMMddHHmmss");
        //        redisTemplate.delete(time+"_"+split[1]);
        //    });
        //});
        AccountInfo accountInfo = redisTemplate.opsForValue().get(key);
        Optional.ofNullable(accountInfo)
                        .ifPresent(a -> a.setAuthorities(accountInfo.getAuthority().stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList())));
        Optional.ofNullable(accountInfo)
                .orElseThrow(() -> new RuntimeException("account could not found"));
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(accountInfo.getAccount(), accountInfo.getPassword(),accountInfo.getAuthorities());
        authenticationToken.setDetails(key);
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        //放行
        filterChain.doFilter(httpServletRequest,httpServletResponse);
    }
}